#!/usr/bin/env python

"""
Game Baker - Main Game Designer GUI

An open source, cross platform game design system
http://code.google.com/p/game-baker

ps sorry about the state of the code for the GUI, 
it's due for a cleanup (issue 28) - SEE BELOW

- UPDATE on code layout - 2 May 2008:
  Have split this file into two.
  MainGTK now inherits from 
  GUI.main_window_events.main_window_events
  (which should contain all event handlers)
- I will try to keep all code specific
  to the current GUI in that class,
  and all general purpose code for editing
  a game in this class (which needs to be 
  abstracted from the code currently in 
  main_window_events).
  (so we can port to the OLPC more easily)
- I've set up the inheritence in an order 
  that doesn't make sense, but this is a 
  work in progress.
  TimWintle

"""

import sys,os
import runtime
import gobject
import game,GUI.treeview
from pygame.locals import *

try:
     import pygtk
     pygtk.require("2.0")
except: pass

try:
    import gtk
    import gtk.glade
except: sys.exit(1)


def find_item_name(dic,item):
    a = [name for name in dic.keys() if dic[name] == item]
    
    if not len(a) == 1:
        return None
    else:
        return a[0]


def hide_window(widget=None,param2=None):
    """Standard Method to prevent a window being destroyed"""
    widget.hide()
    return True


from GUI.main_window_events import main_window_events


class MainGTK(main_window_events):
    """Main Game Baker GUI class
        Event Handlers are inherited from main_window_events"""

    def __init__(self):
        
        #Set the Glade file
        self.gladefile = "GUI/gamebaker.glade/gamebaker.glade" 
        self.wTree = gtk.glade.XML(self.gladefile) 
        
        def show_about(widget = None):
            self.wTree.get_widget("aboutdialog1").show()

        self.treeviewhelp = GUI.treeview.treeview_helper(self.wTree.get_widget("treeview1"))

        # Define event handlers for Gtk objects
        dic = { "on_wnd_main_destroy" : gtk.main_quit ,
                "on_new1_activate" : self.new_game,
                "on_quit1_activate" : gtk.main_quit,
                "on_open1_activate" : self.open_file,
                "on_save1_activate" : self.save_file,
                "on_save_as1_activate" : self.save_file_as,
                "on_about1_activate" : show_about,
                "on_refresh1_activate":self.treeviewhelp.update_item_list,
                "on_add_object1_activate":self.new_game_object,
                "on_add_workstate1_activate":self.new_workstate,
                "on_play1_activate":self.run_game,
                "on_btn_run_clicked":self.run_game,
                "on_treeview1_row_activated":self.open_properties,
                "on_treeview_click":self.treeview_click,
                "on_btn_new_item_clicked":self.add_item_choice,
                "on_wnd_new_item_destroy_event":hide_window,
                "on_wnd_new_item_destroy_event":hide_window,
                "wnd_delete_event":hide_window,
                "on_cbxworkstateevents_changed":self.change_event_selected,
                "on_close1_activate":self.closegame,
                "btn_save_event":self.save_event,
                "on_btn_undo_event_changes":self.change_event_selected,
                "on_btn_workstate_ok":self.workstate_ok,
                "on_btn_gamescreen_colourpicker_clicked":self.choose_background_colour_gamescreen,
                "on_btn_gamescreen_ok_clicked":self.gamescreen_ok,
                "on_btn_obj_ok_clicked":self.object_ok,
                "on_gameproperties1_activate":self.show_game_properties,
                "on_mnu_import_sprite_activate":self.import_sprite,
                "on_btn_game_ok_clicked":self.game_properties_ok,
                "on_btn_workstate_cancel":self.workstate_cancel,
                "on_btn_new_gamescreen":self.new_game_screen,
                "on_btn_add_obj_to_gamescreen_clicked":self.add_obj_to_gamescreen,
                "show_new_event_popup":self.show_new_event_popup,
                "show_item_popup":self.show_item_popup,
                "new_init_event":(lambda x:self.add_new_event(runtime.EVENT_INIT)),
                "new_iter_event":(lambda x:self.add_new_event(runtime.EVENT_ITERATION)),
                "new_offscreen_event":(lambda x:self.add_new_event(runtime.EVENT_OFFSCREEN)),
                "new_keydown_left_event":(lambda x:self.add_new_event(runtime.EVENT_KEYDOWN * K_LEFT)),
                "new_keydown_right_event":(lambda x:self.add_new_event(runtime.EVENT_KEYDOWN * K_RIGHT)),
                "new_keydown_up_event":(lambda x:self.add_new_event(runtime.EVENT_KEYDOWN * K_UP)),
                "new_keydown_down_event":(lambda x:self.add_new_event(runtime.EVENT_KEYDOWN * K_DOWN)),

                "new_keyup_left_event":(lambda x:self.add_new_event(runtime.EVENT_KEYUP * K_LEFT)),
                "new_keyup_right_event":(lambda x:self.add_new_event(runtime.EVENT_KEYUP * K_RIGHT)),
                "new_keyup_up_event":(lambda x:self.add_new_event(runtime.EVENT_KEYUP * K_UP)),
                "new_keyup_down_event":(lambda x:self.add_new_event(runtime.EVENT_KEYUP * K_DOWN)),
                "new_l_mouse_up_event":(lambda x:self.add_new_event(runtime.EVENT_LMOUSEUP )),
                "new_r_mouse_up_event":(lambda x:self.add_new_event(runtime.EVENT_RMOUSEUP )),
                "new_timer_event":(lambda x:self.add_new_event(runtime.EVENT_TIMER )),
                "on_delete1_activate":self.delete_item,
                "on_popup_new_activate":self.new_item_from_treeview,
                "gamescreen_delete_initial_object":self.gamescreen_delete_initial_object

                }

        # Tell gtk to use these event handlers
        self.wTree.signal_autoconnect(dic)

        self.game = None

        self.selectedworkstate=None

        # Blank filename as filename is unknown
        self.filename = ""


        # Extra initialisation of combo boxes
        def init_combo_box(name):
        	cb = self.wTree.get_widget(name)
        	cell = gtk.CellRendererText()
        	cb.pack_start(cell,True)
        	cb.add_attribute(cell,'text',0)
        	
        init_combo_box("cbxworkstateevents")
        init_combo_box("cbx_workstateoptns")
        init_combo_box("cbx_gamescreen_object_options")
        


        #treeview_gamescreen_objects
        treeview = self.wTree.get_widget("treeview_gamescreen_objects")
        column = gtk.TreeViewColumn("Name"
                    , gtk.CellRendererText(),
                    text=1) # position of column
        treeview.append_column(column)
        column = gtk.TreeViewColumn("Type"
                    , gtk.CellRendererText(),
                    text=2) # position of column
        treeview.append_column(column)


    def delete_gameobject(self,go):
        name = find_item_name(self.game.gameobjects,go)
        del self.game.gameobjects[name]
        # TODO Have to delete or warn about references
    
    def delete_sprite(self,sprite):
        name = find_item_name(self.game.sprites,sprite)
        del self.game.sprites[name]
        # TODO Have to delete or warn about references

    def delete_gamescreen(self,gs):
        name = find_item_name(self.game.gamescreens,gs)
        del self.game.gamescreens[name]
        # TODO Have to delete or warn about references

    def delete_workstate(self,workstate):
        name = find_item_name(self.game.workstates,workstate)
        del self.game.workstates[name]
        # TODO Have to delete or warn about references

    def run_game(self,widget = None):
        """Runs a game"""
        
        debug(self.game)
        #runtime.run_game(self.game)

    def import_external_sprite(self,filename):
        if not filename == "":
            import gbfileio
            newsprite = gbfileio.loadgame(filename,typ="sprite")
            name = ""
            try:
                name = newsprite.name
            except: pass
            if name == "":
                i = 1
                while self.game.sprites.has_key("ImportedSprite%d"%i):
                    i+=1
                name = "ImportedSprite%d"%i
            self.game.sprites[name] = newsprite


def debug(game):
    try:
        try:
            runtime.run_game(game)
        except runtime.gb_runtime_exception, inst:
            msg = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,buttons=gtk.BUTTONS_CLOSE)
            errormessage = """<b>Exception:</b> %s \n<b>Error:</b> %s"""%(inst.log,str(inst.orig).replace("<","&lt;").replace(">","&gt;"))
            msg.set_markup(errormessage)
            result = msg.run()
            msg.destroy()
    except Exception, inst:
        print inst,str(inst)




if __name__ == "__main__":
    h = MainGTK()
    gtk.main()

